from django.shortcuts import render

# Create your views here.
from utils.views import LoginRequiredJSONMixin
from django.views import View
import json
from apps.goods.models import SKU
from django.http import JsonResponse
from django_redis import get_redis_connection

import pickle
import base64
from apps.goods.models import SKU
class CartsView(View):
    """购物车管理"""
    def post(self,request):
        """添加商品到购物车"""
        # 1.拿到前端数据
        datas=json.loads(request.body.decode())
        sku_id=datas.get('sku_id')
        count=datas.get('count')
        selected=datas.get('selected')

        # 2.校验数据
        try:#判断商品是否存在
            SKU.objects.get(id=sku_id)
        except Exception:
            return JsonResponse({'code':400,'errmsg':'商品错误'})

        try:#给商品数量转为int
            count=int(count)
        except Exception:
            count=1
        # 判断是否选中
        if selected in (None,False):
            selected=False
            def is_selected(n):
                return -abs(n)
        else:
            selected=True
            def is_selected(n):
                return abs(n)

        # 3.判断用户是否登录
        if request.user.is_authenticated:#True就是用户登录了
            # 4.登录了保存到redis数据库
            cli=get_redis_connection('carts')
            # user_id:{sku_id:-count/count(-表示未选择)}  redis数据格式
            #     4.1判断商品是否已保存到数据库
            skuCarts=cli.hget(request.user.id,sku_id)
            if skuCarts is None:
                #     4.2没有保存，创建数据
                cli.hset(request.user.id,sku_id,is_selected(count))
            else:
                #4.3有保存就数量加count
                cli.hset(request.user.id, sku_id, is_selected(int(skuCarts)+is_selected(count)))
            return JsonResponse({'code':0,'errmsg':'ok','count':count})

        # 5.没有登录保存到cookie
        #     5.1判断是否已保存到cookie
        if request.COOKIES.get('carts') is None:
            #     5.2没有保存，创建数据
            #数据格式 {sku_id:{count:xxx,selected:xxx},}
            carts_cookie={}
            carts_cookie[str(sku_id)]={'count':count,'selected':selected}
        else:
            #进行base64解码
            carts_cookie = request.COOKIES.get('carts').replace("'",'')[1:].encode('utf-8') #浏览器把我们二进制数据改为了str，我们需要格式化一下数据
            carts_cookie=pickle.loads(base64.b64decode(carts_cookie))
            if str(sku_id) in carts_cookie: #查看cookie是否有指定商品
                #有商品数量加count
                carts_cookie[str(sku_id)]['count']+=count
            else:
                #     5.3没有改商品就添加就数量加count
                carts_cookie[str(sku_id)] = {'count': count, 'selected': selected}
        #     5.4数据进行base64编码
        carts_cookie=base64.b64encode(pickle.dumps(carts_cookie))
        # 6.返回json数据
        response=JsonResponse({'code':0,'errmsg':'ok','count':count})
        response.set_cookie('carts',carts_cookie,max_age=7*24*3600)
        return response

    def get(self,request):
        """展示购物车商品"""
        #购物车数据
        carts_data = {}
        # 1.判断用户是否登录
        if request.user.is_authenticated:
            # 2.登录用户从redis中读取数据，没有数据返回空字典
            #获得redis数据库连接
            cli = get_redis_connection('carts')
            user_carts=cli.hgetall(request.user.id)
            if len(user_carts)==0: #判断用户购物车是否有数据
                #没有数据，返回
                return JsonResponse({'code':400,'errmsg':'ok','cart_skus':user_carts})
            #有数据，通过用户id查询指定用户的购物车数据,格式化为cookie一样的数据，到时候统一格式化给前端
            for k,v in user_carts.items():
                k=k.decode()
                v=v.decode()
                selected=False
                if int(v) > 0:
                    selected=True
                carts_data[k]={'count':abs(int(v)),'selected':selected}
        else:
            # 3.未登录从cookie中读取购物车数据，没有数据返回空字典
            if request.COOKIES.get('carts') is None:
                return JsonResponse({'code': 400, 'errmsg': 'ok', 'cart_skus': {}})
            #有数据格式化二进制数据拿到字典数据
            # 进行base64解码
            carts_cookie = request.COOKIES.get('carts').replace("'", '')[1:].encode('utf-8')  # 浏览器把我们二进制数据改为了str，我们需要格式化一下数据
            carts_data = pickle.loads(base64.b64decode(carts_cookie))#进行base64解码

        #去mysql查询商品信息
        sku_datas=SKU.objects.filter(id__in=carts_data.keys())


        #格式化数据给前端
        cart_skus=[]
        for sku in sku_datas:
            # 默认图片判断
            if 'http' in str(sku.default_image) or r'/img' in str(sku.default_image):
                default_image_url=str(sku.default_image)
            else:
                default_image_url = 'http://192.168.182.5:8888/'+str(sku.default_image)
            cart_skus.append({
                'id':sku.id,
                'name':sku.name,
                'count':carts_data[str(sku.id)]['count'],
                'selected':carts_data[str(sku.id)]['selected'],
                'default_image_url':default_image_url,
                'price':str(sku.price),
                'amount':str(float(sku.price) * float(carts_data[str(sku.id)]['count'])) #总价
            })

        return JsonResponse({'code':0,'errmsg':'ok','cart_skus':cart_skus})

    def put(self,request):
        """修改购物车商品"""
        #1.拿到前端数据
        datas=json.loads(request.body.decode())
        sku_id=datas.get('sku_id')
        count=datas.get('count')
        selected=datas.get('selected')
        if selected in (None,False):
            selected=False
            def is_selected(n):
                return -abs(n)
        else:
            selected=True
            def is_selected(n):
                return abs(n)
        #2.登录用户修改redis
        if request.user.is_authenticated:
            #获得redis连接
            cli=get_redis_connection('carts')
            # 更改数据
            cli.hset(request.user.id,sku_id,is_selected(count))
        else:
            #3.未登用户修改cookie
            # 进行base64解码,拿cookie字典
            carts_cookie = request.COOKIES.get('carts').replace("'", '')[1:].encode('utf-8')  # 浏览器把我们二进制数据改为了str，我们需要格式化一下数据
            carts_data = pickle.loads(base64.b64decode(carts_cookie))  # 进行base64解码
            #更改数据
            carts_data[str(sku_id)]['count']=count
            carts_data[str(sku_id)]['selected']=selected
            #进行base64加密，返回给前端
            carts_data=base64.b64encode(pickle.dumps(carts_data))
            response=JsonResponse({'code':0,'errmsg':'ok','cart_sku':{'sku_id':sku_id,'count':count,'selected':selected}})
            response.set_cookie('carts',carts_data,max_age=60*60*24*365)
            return response
        #4.返回json数据
        return JsonResponse({'code':0,'errmsg':'ok','cart_sku':{'sku_id':sku_id,'count':count,'selected':selected}})

    def delete(self,request):
        """删除购物车商品"""
        # 1.拿到前端数据
        sku_id=json.loads(request.body.decode()).get('sku_id')
        # 2.用户登录删除redis
        if request.user.is_authenticated:
            # 获得redis连接
            cli=get_redis_connection('carts')
            # 删除指定用户的商品
            cli.hdel(request.user.id,sku_id)
        else:
            # 3.用户未登录删除cookie
            # base64解码
            carts_cookie = request.COOKIES.get('carts').replace("'", '')[1:].encode('utf-8')  # 浏览器把我们二进制数据改为了str，我们需要格式化一下数据
            carts_data = pickle.loads(base64.b64decode(carts_cookie))  # 进行base64解码
            # 删除指定商品
            del carts_data[str(sku_id)]
            # base64编码
            carts_data=base64.b64encode(pickle.dumps(carts_data))
            # 保存cookie
            response=JsonResponse({'code':0,'errmsg':'ok'})
            response.set_cookie('carts',carts_data,max_age=60*60*24*365)
            # 返回数据
            return response
        # 4.返回json数据
        return JsonResponse({'code':0,'errmsg':'ok'})

class CartsSelectAllView(View):
    """全选购物车商品"""

    def put(self,request):
        # 1.接受前端数据
        selected=json.loads(request.body.decode()).get('selected')
        # 2.登录用户将redis数据库商品全选
        if request.user.is_authenticated:
            # 连接数据库
            cli=get_redis_connection('carts')
            #创建管道
            pip_cli=cli.pipeline()
            # 将指定用户的所有商品全部设置为选中
            skus=cli.hgetall(request.user.id)
            def selected_all(selected):
                if selected:
                    for k,v in skus.items():
                        pip_cli.hset(request.user.id,k.decode(),abs(int(v.decode())))
                else:
                    for k,v in skus.items():
                        pip_cli.hset(request.user.id,k.decode(),-abs(int(v.decode())))
                pip_cli.execute()
            if len(skus) > 0: # >0 代表有商品
                selected_all(selected)

        else:
            # 3.未登录用户将cookie里面的商品全选
            # 拿到cookie进行base64解码
            carts_cookie = request.COOKIES.get('carts').replace("'", '')[1:].encode('utf-8')  # 浏览器把我们二进制数据改为了str，我们需要格式化一下数据
            carts_data = pickle.loads(base64.b64decode(carts_cookie))  # 进行base64解码
            #将所有商品设置为选中
            if len(carts_data) > 0: # > 0 有商品
                if selected:
                    for k in carts_data:
                        carts_data[k]['selected']=True
                else:
                    for k in carts_data:
                        carts_data[k]['selected']=False
            #继续base64加密
            carts_data=base64.b64encode(pickle.dumps(carts_data))
            # 保存到cookie
            respose=JsonResponse({'code':0,'errmsg':'ok'})
            respose.set_cookie('carts',carts_data,60*60*24*365)
            #返回数据给前端
            return respose

        # 4.返回json数据
        return JsonResponse({'code':0,'errmsg':'ok'})


class CartsSimpleView(View):
    """商品页面右上角购物车"""
    def get(self,request):
        cart_skus=[] #定义一个简单购物车商品列表
        # 1.判断用户是否登录
        if request.user.is_authenticated:
            # 2.登录用户读取指定用户redis数据库商品
            # 连接redis数据库
            cli=get_redis_connection('carts')
            # 查询指定用户数据
            carts_redis=cli.hgetall(request.user.id)
            #判断是否有商品，没有直接返回
            if not len(carts_redis) > 0:
                return JsonResponse({'code':0,'errmsg':'购物车没商品','cart_skus':cart_skus})
            # 有商品查询mysql到商品信息，数据格式化
            skus=SKU.objects.filter(id__in=[i.decode() for i in carts_redis.keys()])
            for sku in skus:
                # 默认图片判断
                if 'http' in str(sku.default_image) or r'/img' in str(sku.default_image):
                    default_image_url = str(sku.default_image)
                else:
                    default_image_url = 'http://192.168.182.5:8888/' + str(sku.default_image)
                cart_skus.append({
                    'id':sku.id,
                    'name':sku.name,
                    'count':abs(int(carts_redis[str(sku.id).encode()].decode())),
                    'default_image_url':default_image_url
                })
        else:
            # 3.未登录用户读取cookie中的商品
            #查看是否cookie中有购物车信息，没有就直接返回
            if request.COOKIES.get('carts') is None:
                return JsonResponse({'code': 0, 'errmsg': '购物车没商品', 'cart_skus': cart_skus})
            # 读取cookie进行base64解密
            carts_cookie = request.COOKIES.get('carts').replace("'", '')[1:].encode('utf-8')  # 浏览器把我们二进制数据改为了str，我们需要格式化一下数据
            carts_cookie = pickle.loads(base64.b64decode(carts_cookie))  # 进行base64解码
            # 判断cookie是否有商品，没有直接返回
            if not len(carts_cookie) > 0:
                return JsonResponse({'code': 0, 'errmsg': '购物车没商品', 'cart_skus': cart_skus})
            # 有商品，查询mysql商品信息
            skus=SKU.objects.filter(id__in=carts_cookie.keys())
            # 格式化数据
            for sku in skus:
                if 'http' in str(sku.default_image) or r'/img' in str(sku.default_image):
                    default_image_url = str(sku.default_image)
                else:
                    default_image_url = 'http://192.168.182.5:8888/' + str(sku.default_image)
                cart_skus.append({
                    'id':sku.id,
                    'name':sku.name,
                    'count':carts_cookie[str(sku.id)]['count'],
                    'default_image_url': default_image_url
                })
        # 4.返回json
        return JsonResponse({'code': 0, 'errmsg': '购物车没商品', 'cart_skus': cart_skus})












